package org.jeecg.common.sdk.ocr.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import org.jeecg.common.sdk.ocr.BaiduOcr;
import org.jeecg.common.sdk.ocr.entity.BaiduOcrWord;
import org.jeecg.common.sdk.ocr.entity.WordsResultDTO;
import org.jeecg.common.sdk.ocr.service.entity.BaoGaoDTO;
import org.jeecg.common.sdk.ocr.service.entity.BaoGaoFlatVO;
import org.jeecg.common.sdk.ocr.service.entity.ShiJianDTO;
import org.jeecg.common.util.Vars;
import org.jeecg.common.util.easyexcel.EasyExcelWriteUtil;
import io.swagger.annotations.ApiOperation;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author zjarlin
 * @since 2023/11/20 13:35
 */
@RestController
@RequestMapping("/reportOcr")
public class BaoGaoOcrService {
    @NotNull
    private static BaoGaoDTO getBaoGaoDTO(String string) {
        BaiduOcrWord parse = JSON.parseObject(string, BaiduOcrWord.class);
        List<WordsResultDTO> wordsResult = parse.getWords_result();

        String collect = wordsResult.stream().map(e -> {
            String words = e.getWords();
            return words;
        }).collect(Collectors.joining(System.lineSeparator()));

        //vo     行
        List<String> strings0 = StrUtil.splitTrim(collect, System.lineSeparator());

        List<String> list = Arrays.asList(
                "工程名称", "工程编号", "报告编号", "工程部位", "样品编号", "委托日期", "建设单位", "送样人", "试验日期", "委托单位", "见证人", "报告日期", "见证单位", "累计养护温度", "强度等级", "施工单位", "检测类别", "制作日期", "生产厂家", "代表批量", "是否拆模", "检测依据", "说明", "备注"
        );
        Map<String, String> collect1 = list.stream().collect(Collectors.toMap(e -> e, e -> {
            Integer integer = IntStream.range(0, strings0.size()).filter(i -> {
                String s1 = strings0.get(i);
                return StrUtil.containsIgnoreCase(s1, e);
            }).boxed().findAny().orElse(null);
            String s = integer == null ? "" : strings0.get(integer + 1);
            return s;
        }));
        BaoGaoDTO baoGaoDTO = BeanUtil.mapToBean(collect1, BaoGaoDTO.class, CopyOptions.create());
        if (baoGaoDTO.get生产厂家().contains("代表批量")) {
            baoGaoDTO.set生产厂家("---");
        }

        if (baoGaoDTO.get代表批量().contains("是否拆模：")) {
            baoGaoDTO.set代表批量("---");
        }
        if (baoGaoDTO.get是否拆模().contains("(m3):")) {
            baoGaoDTO.set是否拆模("---");
        }
        if (baoGaoDTO.get说明().contains("异议。")) {
            baoGaoDTO.set说明("1、若对报告有异议，应于收到报告之日起15日内，以书面形式向检测单位提出，逾期视为对报告无异议。\n" +
                              "2、未加盖本公司检验报告专用章，报告无效。\n");
        }


        String s = StrUtil.subBetween(collect, "试件编号", "检测依据");


//        试件行

        List<String> strings = StrUtil.splitTrim(s, System.lineSeparator());
        ShiJianDTO shiJianDTO = new ShiJianDTO();
        shiJianDTO.set试件编号("1");
        shiJianDTO.set龄期(strings.get(13));
        shiJianDTO.set养护条件(strings.get(14));
        shiJianDTO.set试件规格(strings.get(15));
        shiJianDTO.set实测值(strings.get(11));
        shiJianDTO.set强度代表值(strings.get(17));
        shiJianDTO.set达到设计强度等级(strings.get(18));

        ShiJianDTO shiJianDTO1 = new ShiJianDTO();
        shiJianDTO1.set试件编号("2");
        shiJianDTO1.set龄期(strings.get(13));
        shiJianDTO1.set养护条件(strings.get(14));
        shiJianDTO1.set试件规格(strings.get(15));
        shiJianDTO1.set实测值(strings.get(16));
        shiJianDTO1.set强度代表值(strings.get(17));
        shiJianDTO1.set达到设计强度等级(strings.get(18));

        ShiJianDTO shiJianDTO2 = new ShiJianDTO();
        shiJianDTO2.set试件编号("3");
        shiJianDTO2.set龄期(strings.get(13));
        shiJianDTO2.set养护条件(strings.get(14));
        shiJianDTO2.set试件规格(strings.get(15));
        shiJianDTO2.set实测值(strings.get(20));
        shiJianDTO2.set强度代表值(strings.get(17));
        shiJianDTO2.set达到设计强度等级(strings.get(18));
        List<ShiJianDTO> list1 = Arrays.asList(shiJianDTO, shiJianDTO1, shiJianDTO2);

        baoGaoDTO.setShiJianDTOS(list1);
        return baoGaoDTO;
    }

    public static List<BaoGaoFlatVO> flatBaoGaoDTO(BaoGaoDTO baoGaoDTO) {
        List<ShiJianDTO> shiJianDTOS = baoGaoDTO.getShiJianDTOS();
        if (shiJianDTOS.isEmpty()) {
//            BaoGaoFlatVO baoGaoFlatVO = new BaoGaoFlatVO();
            return new ArrayList<>();
        }
        List<BaoGaoFlatVO> collect = shiJianDTOS.stream().map(e -> {
            BaoGaoFlatVO convert = Convert.convert(BaoGaoFlatVO.class, e);
            BeanUtil.copyProperties(baoGaoDTO, convert);
            return convert;
        }).collect(Collectors.toList());

        return collect;
    }

    public static List<BaoGaoFlatVO> flatBaoGaoDTOOne(BaoGaoDTO baoGaoDTO) {
        List<BaoGaoFlatVO> baoGaoFlatVOS = flatBaoGaoDTO(baoGaoDTO);
        BaoGaoFlatVO baoGaoFlatVO = baoGaoFlatVOS.stream().findAny().orElse(null);
        return baoGaoFlatVO == null ? new ArrayList<>() : Arrays.asList(baoGaoFlatVO);
    }

    public static void main(String[] args) {
        String stringBaogaoJson = "{\"words_result\":[{\"words\":\"MA\"},{\"words\":\"河南金豫检验检测技术有限公司\"},{\"words\":\"171601060005\"},{\"words\":\"混凝土抗压强度检测报告\"},{\"words\":\"有效期2023年1月3日\"},{\"words\":\"单位资质：\"},{\"words\":\"03028\"},{\"words\":\"工程名称：\"},{\"words\":\"弘雅苑9#楼\"},{\"words\":\"工程编号：\"},{\"words\":\"2100116\"},{\"words\":\"报告编号：\"},{\"words\":\"J1220300118850\"},{\"words\":\"工程部位：\"},{\"words\":\"27层墙柱、顶板、梁、楼梯\"},{\"words\":\"样品编号：\"},{\"words\":\"J122048143\"},{\"words\":\"委托日期：\"},{\"words\":\"2022-09-13\"},{\"words\":\"建设单位：\"},{\"words\":\"洛阳尊和置业有限公司\"},{\"words\":\"送样人：\"},{\"words\":\"方松\"},{\"words\":\"试验日期：\"},{\"words\":\"2022-09-13\"},{\"words\":\"委托单位：\"},{\"words\":\"洛阳尊和置业有限公司\"},{\"words\":\"见证人：\"},{\"words\":\"杜晨哲\"},{\"words\":\"报告日期：\"},{\"words\":\"2022-09-14\"},{\"words\":\"见证单位：\"},{\"words\":\"广源管理咨询有限公司\"},{\"words\":\"累计养护\"},{\"words\":\"强度等级：\"},{\"words\":\"C30\"},{\"words\":\"温度（℃）：\"},{\"words\":\"施工单位：\"},{\"words\":\"中建三局集团有限公司\"},{\"words\":\"检测类别：\"},{\"words\":\"见证送检\"},{\"words\":\"制作日期：\"},{\"words\":\"2022-08-18\"},{\"words\":\"生产厂家:\"},{\"words\":\"代表批量\"},{\"words\":\"是否拆模：\"},{\"words\":\"(m3):\"},{\"words\":\"抗压强度\"},{\"words\":\"(MPa)\"},{\"words\":\"试件编号\"},{\"words\":\"龄期\"},{\"words\":\"达到设计\"},{\"words\":\"(d)\"},{\"words\":\"养护条件\"},{\"words\":\"试件规格\"},{\"words\":\"强度等级\"},{\"words\":\"(mm)\"},{\"words\":\"实测值\"},{\"words\":\"强度代表值\"},{\"words\":\"(%)\"},{\"words\":\"l\"},{\"words\":\"31.0\"},{\"words\":\"2\"},{\"words\":\"26\"},{\"words\":\"同条件养护\"},{\"words\":\"100×100×100\"},{\"words\":\"30.8\"},{\"words\":\"34.1\"},{\"words\":\"113.7\"},{\"words\":\"3\"},{\"words\":\"28.1\"},{\"words\":\"检测依据\"},{\"words\":\"GB/T50081-2019\"},{\"words\":\"1、若对报告有异议，应于收到报告之日起15日内，以书面形式向检测单位提出，逾期视为对报告无\"},{\"words\":\"说明\"},{\"words\":\"异议。\"},{\"words\":\"2、未加盖本公司检验报告专用章，报告无效。\"},{\"words\":\"备注\"},{\"words\":\"强度代表值已除以折算系数0.88\"},{\"words\":\"检测技\"},{\"words\":\"试验\"},{\"words\":\"卫\"},{\"words\":\"唐利峰\"},{\"words\":\"审核\"},{\"words\":\"许珠琳\"},{\"words\":\"批准\"},{\"words\":\"树\"},{\"words\":\"地址：洛阳市太康东路与汇通街交叉口顺兴信息产业园7号楼\"},{\"words\":\"河南金豫检验检测技术有限公司\"},{\"words\":\"电话：0379-65265550\"},{\"words\":\"共！页，第1页\"}],\"words_result_num\":91,\"log_id\":1726491465718836271}";
        BaoGaoDTO baoGaoDTO = getBaoGaoDTO(stringBaogaoJson);
        System.out.println(baoGaoDTO);

    }

    /**
     * 报告解析3个试件都返回
     * 如果single为true则只返回一个值
     *
     * @param file 入参
     * @return {@link List }<{@link BaoGaoFlatVO }>
     * @author zjarlin
     * @since 2023/11/20
     */

    @NotNull
    private static List<BaoGaoFlatVO> getBaoGaoFlatVOS(MultipartFile[] file) {
        return getBaoGaoFlatVOS(file, 1);
    }

    /**
     * 报告解析3个试件都返回
     * 如果single为1则只返回一个值
     * 如果single为3则只返回多个值
     *
     * @param file 入参
     * @return {@link List }<{@link BaoGaoFlatVO }>
     * @author zjarlin
     * @since 2023/11/20
     */

    @NotNull
    private static List<BaoGaoFlatVO> getBaoGaoFlatVOS(MultipartFile[] file, Integer single) {
        List<BaoGaoFlatVO> collect = Arrays.stream(file).flatMap(e -> {
                    String ocrString = BaiduOcr.getOcrString(e);
                    BaoGaoDTO baoGaoDTO = getBaoGaoDTO(ocrString);
                    List<BaoGaoFlatVO> baoGaoFlatVOS = Objects.equals(single, 1) ? flatBaoGaoDTOOne(baoGaoDTO) : flatBaoGaoDTO(baoGaoDTO);
                    return baoGaoFlatVOS.stream();
                })
                .sorted(Comparator.comparing(BaoGaoFlatVO::get委托日期))
                .sorted(Comparator.comparing(BaoGaoFlatVO::get工程部位))
                .collect(Collectors.toList());
        return collect;
    }

    /**
     * 报告解析3个试件都返回
     *
     * @param file 入参
     * @return {@link List }<{@link BaoGaoFlatVO }>
     * @author zjarlin
     * @since 2023/11/20
     */

    @ApiOperation("获取解析后的报告List single为3则解析全部试件,为1则解析1个默认仅解析一个(业务目前仅需要一个)")
    @GetMapping("/obtainTheParsedReportList")
    private List<BaoGaoFlatVO> obtainTheParsedReportList(MultipartFile[] file, Integer single) {
        return getBaoGaoFlatVOS(file, single);
    }
    @PostMapping("/exportParsedReportDataSingleRow")
    @ApiOperation("导出解析的单行试块报告数据")
    public void exportParsedReportDataSingleRowlist(MultipartFile[] file) {
        List<BaoGaoFlatVO> collect = getBaoGaoFlatVOS(file);
        String fileName = "报告解析" + Vars.timeSuffix;
        EasyExcelWriteUtil.listExport(collect, fileName);
    }

    @PostMapping("exportParsedReportData")
    @ApiOperation("导出解析的试块报告数据")
    public void 导出list(MultipartFile[] file) {
        List<BaoGaoFlatVO> collect = getBaoGaoFlatVOS(file,3);
        String fileName = "报告解析" + Vars.timeSuffix;
        EasyExcelWriteUtil.listExport(collect, fileName);
    }


}
